import logging
import math
import os
import time
from typing import Optional

from lxautoplat.case import CrawlerApp

from crawler.service.automation_platform_request import global_automation_platform
from crawler.service.industrial_service import IndustrialService

LOGGER = logging.getLogger(__name__)


def _get_current_time():
    """获取当前时间戳"""
    return time.time()


async def _handle_success(start_time: float):
    """处理任务成功情况"""
    duration = _get_current_time() - start_time
    duration = math.floor(duration)
    await global_automation_platform.end_run(
        status="SUCCESS", failure_reason=None, progress=100, duration=duration
    )
    LOGGER.info("任务执行成功，耗时: %d 秒", duration)


async def _handle_failure(failure_reason: str, start_time: Optional[float]):
    """处理任务失败情况"""
    duration = _get_current_time() - start_time if start_time else 0
    duration = math.floor(duration)
    await global_automation_platform.end_run(
        status="FAILED", failure_reason=failure_reason, progress=0, duration=duration
    )


def _check_required_params(script_param):
    """检查必要参数"""
    task_id = script_param.get("task_id")
    automation_platform = script_param.get("automation_platform", {})
    search = script_param.get("search")
    file_name = script_param.get("file_name", "")
    file_path = os.path.join(script_param.get("file_path", ""), file_name)

    if not all([task_id, automation_platform, search, file_name, file_path]):
        LOGGER.error("缺少执行参数，无法继续执行")
        raise Exception("缺少执行参数，无法继续执行")
    return task_id, automation_platform, search, file_name, file_path


class IndustrialApp(CrawlerApp):
    async def run_async(
            self, browser: Optional[object] = None, playwright: Optional[object] = None
    ):
        start_time = None
        try:
            # 初始化配置
            script_param = self.config.script_param
            LOGGER.info("开始初始化请求对象 %s", script_param)

            # 检查必要参数
            task_id, automation_platform, search, file_name, file_path = (
                _check_required_params(script_param)
            )
            script_type = script_param.get("script_type", "")

            global_automation_platform.set_task_id(task_id)
            global_automation_platform.set_upload_data_url(
                automation_platform.get("upload_data_url")
            )
            global_automation_platform.set_upload_file_url(
                automation_platform.get("upload_file_url")
            )
            global_automation_platform.set_file_path(file_path)
            global_automation_platform.set_file_name(file_name)
            LOGGER.info("请求对象初始化完成")

            start_time = _get_current_time()
            LOGGER.info("开始异步执行任务，任务 ID: %s", task_id)
            await global_automation_platform.start_run()

            # 检查是否存在上下文
            if not browser.contexts:
                LOGGER.error("未找到浏览器上下文")
                await _handle_failure("未找到浏览器上下文", start_time)
                return

            context = browser.contexts[0]
            smsService = IndustrialService(context=context)
            await smsService.run_script(search, script_type)

            await _handle_success(start_time)

        except Exception as e:
            # 捕获并记录执行过程中的异常
            LOGGER.error("执行任务时发生错误: %s", str(e), exc_info=True)
            await _handle_failure(str(e), start_time)
            raise e
        finally:
            if browser:
                try:
                    await browser.close()
                    LOGGER.info("浏览器已成功关闭")
                except Exception as e:
                    LOGGER.error("关闭浏览器时发生错误: %s", str(e))
